From: Dan Winship Date: Mon, 1 Aug 2011 19:16:45 +0000 (-0400) Subject: St: fix container paint volumes X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~7996 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=dbeab0ef87d06d32db0678480ae9f0ee933288e9;p=gnome-shell.git St: fix container paint volumes If a container is not clip-to-allocation, then its get_paint_volume() needs to include the paint volumes of all of its children, since they (or their children) may paint outside the container's allocation. Also, if the superclass get_paint_volume() returns FALSE, then the subclass should return FALSE too. https://bugzilla.gnome.org/show_bug.cgi?id=655812 --- diff --git a/src/shell-generic-container.c b/src/shell-generic-container.c index c54ebf278..479cd056b 100644 --- a/src/shell-generic-container.c +++ b/src/shell-generic-container.c @@ -247,34 +247,6 @@ shell_generic_container_finalize (GObject *object) G_OBJECT_CLASS (shell_generic_container_parent_class)->finalize (object); } -/* Based on implementation from clutter-group.c */ -static gboolean -shell_generic_container_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - GList *l, *children; - - children = st_container_get_children_list (ST_CONTAINER (actor)); - - CLUTTER_ACTOR_CLASS (shell_generic_container_parent_class)->get_paint_volume (actor, volume); - - for (l = children; l != NULL; l = l->next) - { - ClutterActor *child = l->data; - const ClutterPaintVolume *child_volume; - - /* This gets the paint volume of the child transformed into the - * group's coordinate space... */ - child_volume = clutter_actor_get_transformed_paint_volume (child, actor); - if (!child_volume) - return FALSE; - - clutter_paint_volume_union (volume, child_volume); - } - - return TRUE; -} - static void shell_generic_container_class_init (ShellGenericContainerClass *klass) { @@ -287,7 +259,6 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass) actor_class->get_preferred_width = shell_generic_container_get_preferred_width; actor_class->get_preferred_height = shell_generic_container_get_preferred_height; actor_class->allocate = shell_generic_container_allocate; - actor_class->get_paint_volume = shell_generic_container_get_paint_volume; actor_class->paint = shell_generic_container_paint; actor_class->pick = shell_generic_container_pick; diff --git a/src/st/st-box-layout.c b/src/st/st-box-layout.c index 0aa5ef2e8..e0b604356 100644 --- a/src/st/st-box-layout.c +++ b/src/st/st-box-layout.c @@ -1020,7 +1020,8 @@ st_box_layout_get_paint_volume (ClutterActor *actor, StBoxLayout *self = ST_BOX_LAYOUT (actor); gdouble x, y; - CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->get_paint_volume (actor, volume); + if (!CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->get_paint_volume (actor, volume)) + return FALSE; /* When scrolled, st_box_layout_apply_transform() includes the scroll offset * and affects paint volumes. This is right for our children, but our paint volume diff --git a/src/st/st-container.c b/src/st/st-container.c index 6283bd700..c2494079c 100644 --- a/src/st/st-container.c +++ b/src/st/st-container.c @@ -427,6 +427,37 @@ st_container_dispose (GObject *object) G_OBJECT_CLASS (st_container_parent_class)->dispose (object); } +static gboolean +st_container_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + StContainerPrivate *priv = ST_CONTAINER (actor)->priv; + GList *l; + + if (!CLUTTER_ACTOR_CLASS (st_container_parent_class)->get_paint_volume (actor, volume)) + return FALSE; + + if (!clutter_actor_get_clip_to_allocation (actor)) + { + /* Based on ClutterGroup/ClutterBox; include the children's + * paint volumes, since they may paint outside our allocation. + */ + for (l = priv->children; l != NULL; l = l->next) + { + ClutterActor *child = l->data; + const ClutterPaintVolume *child_volume; + + child_volume = clutter_actor_get_transformed_paint_volume (child, actor); + if (!child_volume) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } + } + + return TRUE; +} + /* filter @children to contain only only actors that overlap @rbox * when moving in @direction. (Assuming no transformations.) */ @@ -719,6 +750,7 @@ static void st_container_class_init (StContainerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); StWidgetClass *widget_class = ST_WIDGET_CLASS (klass); StContainerClass *container_class = ST_CONTAINER_CLASS (klass); @@ -726,6 +758,8 @@ st_container_class_init (StContainerClass *klass) object_class->dispose = st_container_dispose; + actor_class->get_paint_volume = st_container_get_paint_volume; + widget_class->navigate_focus = st_container_navigate_focus; container_class->get_focus_chain = st_container_real_get_focus_chain; diff --git a/src/st/st-group.c b/src/st/st-group.c index 502957b03..1395af211 100644 --- a/src/st/st-group.c +++ b/src/st/st-group.c @@ -231,34 +231,6 @@ st_group_hide_all (ClutterActor *actor) NULL); } -/* Based on implementation from clutter-group.c */ -static gboolean -st_group_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - GList *l, *children; - - children = st_container_get_children_list (ST_CONTAINER (actor)); - - CLUTTER_ACTOR_CLASS (st_group_parent_class)->get_paint_volume (actor, volume); - - for (l = children; l != NULL; l = l->next) - { - ClutterActor *child = l->data; - const ClutterPaintVolume *child_volume; - - /* This gets the paint volume of the child transformed into the - * group's coordinate space... */ - child_volume = clutter_actor_get_transformed_paint_volume (child, actor); - if (!child_volume) - return FALSE; - - clutter_paint_volume_union (volume, child_volume); - } - - return TRUE; -} - static void st_group_class_init (StGroupClass *klass) @@ -269,7 +241,6 @@ st_group_class_init (StGroupClass *klass) actor_class->get_preferred_height = st_group_get_preferred_height; actor_class->allocate = st_group_allocate; actor_class->paint = st_group_paint; - actor_class->get_paint_volume = st_group_get_paint_volume; actor_class->pick = st_group_pick; actor_class->show_all = st_group_show_all; actor_class->hide_all = st_group_hide_all;